home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / PoliteNotification ƒ / PoliteNotification.π / ShowInitIcon.c < prev   
Text File  |  1992-06-22  |  5KB  |  175 lines

  1. /*
  2.     ShowInitIcon.c : Shows the icon during the init loading time
  3. */
  4.  
  5. /*
  6.     Note: This code is roughly based on an assembly language routine by
  7.         Paul Mercer, Darin Adler, and Paul Snively from an idea by Steve Capps.
  8.         We use this method to be compatible with other Mac INITs.
  9.         
  10.         It was converted to Think C by Eric Shapiro.
  11.             10/6/91        ebs        Added HNoPurge call just to be extra safe.
  12.             4/26/91        ebs        Added wrap-to-next-line support from James W. Walker
  13.             3/29/91        ebs        Changed function name, added CIconHandle typecasts
  14.             12/12/89    ebs        Called ClosePort() to release port memory
  15. */
  16.  
  17.     /* The low memory CurApName is a convenient place to store
  18.         four bytes of information so the next INIT doesn't
  19.         overwrite our ICON.  We store into my_h the horizontal
  20.         pixel location where the next INIT should go.  We checksum
  21.         the value and store the checksum in the next two bytes,
  22.         so that INITs can determine whether they're the 1st one loaded.
  23.     */
  24.     
  25. #define CurApName 0x910
  26.  
  27. extern     short        my_h : CurApName+32-4;    
  28. extern    short        my_check : CurApName+32-2;
  29.  
  30. #ifndef NULL
  31. #define NULL ( (void *)0 )
  32. #endif
  33.  
  34. #define ICON_HEIGHT        32
  35. #define ICON_WIDTH        32
  36. #define    FIRST_X            8            /* don't change this */
  37. #define    BOTTOM_MARGIN    8
  38. #define DEF_MOVE_X_BY    40
  39. #define    CHECKSUM_CONST    0x1021
  40. #define MIN_BIT_DEPTH    4            /* if 16 colors or more, use color icon */
  41.  
  42.  
  43. /*
  44.     ShowInitIcon: Shows the icon specified in the correct place during startup
  45.     
  46.         NOTE:
  47.             If Color QDraw is present and the main device has at least MIN_BIT_DEPTH
  48.             set, we'll look for a color icon ('cicn' resource) first. If we can't
  49.             find one, we'll look for the 'ICN#' resource.
  50.  
  51.         Passed:
  52.             short    icon_num;        'ICN#' or 'cicn' resource id
  53.             short    move_x_by;        Pass -1 for default
  54.             
  55.         Returns:
  56.             int        0=No error, <0=Error number
  57. */
  58. OSErr ShowInitIcon( short icon_num, short move_x_by)
  59. {
  60.     short        err;
  61.     Handle        icon_h=NULL;        /* handle to 'ICN#' or 'cicn' resource */
  62.     Boolean        in_color=FALSE;        /* TRUE='cicn' resource, else 'ICN#' */
  63.     GrafPtr        oldport;
  64.     GrafPort    newport;            /* Entire GrafPort structure */
  65.     Rect         r;                    /* where to put the icon */
  66.     SysEnvRec    sys_rec;
  67.     short        screen_width;
  68.  
  69.         /* check for color quickdraw. If present, check bit depth of mainscreen.
  70.             if >= MIN_BIT_DEPTH, then try to use color icon.
  71.         */
  72.     if ( err = SysEnvirons(1, &sys_rec) )
  73.         return(err);
  74.     if ( sys_rec.hasColorQD )        /* a Mac II or later... */
  75.     {
  76.         GDHandle gdev = GetGDevice();    /* get main screen */
  77.         if ( (*(*gdev)->gdPMap)->pixelSize >= MIN_BIT_DEPTH )
  78.             icon_h = (Handle)GetCIcon(icon_num);
  79.         if ( icon_h != NULL )
  80.             in_color = TRUE;
  81.     }
  82.     
  83.     if ( icon_h == NULL )        /* no icon yet, try a B&W one */
  84.         icon_h = Get1Resource('ICN#', icon_num);
  85.     if ( icon_h == NULL )
  86.         return(resNotFound);    /* we're SOL here */
  87.     HNoPurge( icon_h );
  88.  
  89.     GetPort(&oldport);        /* save old GrafPort for later restoring */
  90.  
  91.         /* open a port so we can draw directly to screen. WindowMgrPort
  92.             may not be initialized at this time.
  93.         */
  94.     OpenPort(&newport);
  95.     SetPort(&newport);
  96.     
  97.         /* do a checksum on low memory to see if we're the 1st icon */
  98.         /* if we are, then set x location. ^=XOR. */
  99.     if ( ((my_h <<1) ^ CHECKSUM_CONST) != my_check )
  100.         my_h = FIRST_X;
  101.  
  102. #ifdef OLD_VERSION
  103.         /* now plot the icon */
  104.     r = newport.portRect;
  105.     r.top = newport.portRect.bottom - (BOTTOM_MARGIN+ICON_HEIGHT);
  106.     r.bottom = newport.portRect.bottom - BOTTOM_MARGIN;
  107.     r.left = my_h;
  108.     r.right = r.left + ICON_WIDTH;
  109. #endif
  110.         /* now plot the icon  4/26/91 updated */
  111.     screen_width = newport.portRect.right - newport.portRect.left;
  112.     screen_width -= screen_width % DEF_MOVE_X_BY;     /* in case screen isn't multiple of 40 */
  113.     r.left = my_h % screen_width;
  114.     r.right = r.left + ICON_WIDTH;
  115.     r.top = newport.portRect.bottom - ((BOTTOM_MARGIN+ICON_HEIGHT) * (1 + my_h / screen_width));
  116.     r.bottom = r.top + ICON_HEIGHT;
  117.     
  118.     if ( in_color )
  119.         PlotCIcon(&r, (CIconHandle)icon_h);        /* Toolbox's plot routine */
  120.     else
  121.         plot_icn(&r, icon_h);                    /* our routine */
  122.     
  123.         /* now offset the low memory location by move_x_by pixels */
  124.     if ( move_x_by == -1 )
  125.         move_x_by = DEF_MOVE_X_BY;
  126.  
  127.     my_h += move_x_by;
  128.     my_check = (my_h<<1) ^ CHECKSUM_CONST;
  129.  
  130.         /* release the icon, restore the port */
  131.     if ( in_color )
  132.         DisposCIcon((CIconHandle)icon_h);
  133.     else
  134.         ReleaseResource(icon_h);
  135.     SetPort(oldport);
  136.     ClosePort(&newport);                        /* ebs 12/12/89 */
  137.     return(0);
  138. }
  139.  
  140.  
  141. /*
  142.     plot_icn : Plots an ICN# (ICON+mask) just the the Finder.
  143. */
  144. plot_icn(r, icn_handle)
  145.     Rect    *r;
  146.     Handle    icn_handle;
  147. {
  148.     BitMap        bm;
  149.     char        flags;
  150.     GrafPtr        cur_port;
  151.     
  152.     flags = HGetState(icn_handle);
  153.     HLock(icn_handle);
  154.     GetPort(&cur_port);
  155.     
  156.         /* we have to set up a BitMap structure to pass to CopyBits. We
  157.             might be able to use CopyMask() call instead, but this should
  158.             work on all Macs and CopyMask is only Mac+ or later. The 1st
  159.             BitMap we use has baseAddr pointing 128 bytes into the ICN#,
  160.             at the 1st bit of the mask. The 2nd BitMap points to the ICON.
  161.         */
  162.     bm.baseAddr = *icn_handle + ICON_WIDTH*ICON_HEIGHT/8;    /* points to mask */
  163.     bm.rowBytes = ICON_WIDTH / 8;            /* ICON_WIDTH/8 must be power of 2 */
  164.     SetRect(&bm.bounds, 0, 0, ICON_WIDTH, ICON_HEIGHT);
  165.  
  166.         /* punch a hole in the Desktop using bit-clear mode and the mask */
  167.     CopyBits(&bm, &cur_port->portBits, &bm.bounds, r, srcBic, NULL);
  168.  
  169.         /* now copy the icon into the punched hole */
  170.     bm.baseAddr = *icn_handle;        /* points to ICON */
  171.     CopyBits(&bm, &cur_port->portBits, &bm.bounds, r, srcOr, NULL);
  172.     
  173.     HSetState(icn_handle, flags);
  174. }
  175.